package com.ihr360.job.core.listener;

import com.ihr360.job.core.ItemProcessListener;
import com.ihr360.job.core.scope.context.SimpleStepContext;
import org.springframework.core.Ordered;

import java.util.Iterator;
import java.util.List;

public class CompositeItemProcessListener<T, S> implements ItemProcessListener<T, S> {

    private OrderedComposite<ItemProcessListener<? super T, ? super S>> listeners = new OrderedComposite<ItemProcessListener<? super T, ? super S>>();

    /**
     * Public setter for the listeners.
     *
     * @param itemReadListeners
     */
    public void setListeners(List<? extends ItemProcessListener<? super T, ? super S>> itemReadListeners) {
        this.listeners.setItems(itemReadListeners);
    }

    /**
     * Register additional listener.
     *
     * @param itemReaderListener
     */
    public void register(ItemProcessListener<? super T, ? super S> itemReaderListener) {
        listeners.add(itemReaderListener);
    }

    /**
     * Call the registered listeners in reverse order, respecting and
     * prioritising those that implement {@link Ordered}.
     * @see com.ihr360.job.core.ItemProcessListener#afterProcess(java.lang.Object,
     * java.lang.Object)
     */
    @Override
    public void afterProcess(T item, S result) {
        for (Iterator<ItemProcessListener<? super T, ? super S>> iterator = listeners.reverse(); iterator.hasNext();) {
            ItemProcessListener<? super T, ? super S> listener = iterator.next();
            listener.afterProcess(item, result);
        }
    }

    /**
     * Call the registered listeners in order, respecting and prioritising those
     * that implement {@link Ordered}.
     * @see com.ihr360.job.core.ItemProcessListener#beforeProcess(java.lang.Object)
     */
    @Override
    public void beforeProcess(T item,SimpleStepContext simpleStepContext) {
        for (Iterator<ItemProcessListener<? super T, ? super S>> iterator = listeners.iterator(); iterator.hasNext();) {
            ItemProcessListener<? super T, ? super S> listener = iterator.next();
            listener.beforeProcess(item,simpleStepContext);
        }
    }

    /**
     * Call the registered listeners in reverse order, respecting and
     * prioritising those that implement {@link Ordered}.
     * @see com.ihr360.job.core.ItemProcessListener#onProcessError(java.lang.Object,
     * java.lang.Exception)
     */
    @Override
    public void onProcessError(T item,SimpleStepContext simpleStepContext, Exception e) {
        for (Iterator<ItemProcessListener<? super T, ? super S>> iterator = listeners.reverse(); iterator.hasNext();) {
            ItemProcessListener<? super T, ? super S> listener = iterator.next();
            listener.onProcessError(item,simpleStepContext, e);
        }
    }

}
